#include <gio/gio.h>
#include <glib.h>

#include "generated-code.h"

#define OFONO_SERVICE_NAME "org.ofono"
#define OFONO_MODEM_PATH "/phonesim"
#define OFONO_NOTIFICATION "org.ofono.PushNotification"
#define NOTIFICATION_AGENT "org.ofono.PushNotificationAgent"
#define AGENT_PATH "/org/ofono/PushNotification"
static GMainLoop *main_loop;

static gboolean on_receive_notification(OrgOfonoPushNotificationAgent *agent, GDBusMethodInvocation *invocation,
        const gchar *notification, const GVariant *info, gpointer user_data) {
    g_print("on_receive_notification get called are you aware of that\n");
    g_print("notification is '%s'\n", notification);
    g_print("type of info is %s\n", g_variant_get_type(info));
    return TRUE;
}

static gboolean on_release(OrgOfonoPushNotificationAgent *agent, GDBusMethodInvocation *invocation, gpointer user_data) {
    g_print("on_release get called are you aware of that\n");
    return TRUE;
}

static gboolean dbus_setup_interface(gpointer user_data) {
    OrgOfonoPushNotificationAgent *agent = org_ofono_push_notification_agent_skeleton_new();
    
    g_signal_connect(agent, "handle-receive-notification", G_CALLBACK(on_receive_notification), user_data);
    g_signal_connect(agent, "handle-release", G_CALLBACK(on_release), user_data);

    return TRUE;
}

static void on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data) {
    g_print("on_bus_acquired conn is 0x%0x, name is '%s'\n", (unsigned int) conn, name);
    dbus_setup_interface(user_data);
}

static void on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data) {
    g_print("on_name_acquired conn is 0x%0x, name is '%s'\n", (unsigned int) conn, name);
}

static void on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data) {
    g_print("on_name_lost conn is 0x%0x, name is '%s'\n", (unsigned int) conn, name);
    //g_main_loop_quit(main_loop);
}

int main(int argc, char **argv) {
    g_type_init();
    main_loop = g_main_loop_new(NULL, FALSE);
    guint owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, NOTIFICATION_AGENT, G_BUS_NAME_OWNER_FLAGS_REPLACE,
            on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL);

    /* register notification agent to oFono, let them know we are here */
    GVariant *agent_path = g_variant_new("(o)", AGENT_PATH);
    GError *error = NULL;
    const GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
    GVariant *result = g_dbus_connection_call_sync(conn, OFONO_SERVICE_NAME, OFONO_MODEM_PATH, OFONO_NOTIFICATION,
            "RegisterAgent", agent_path, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
    if (result == NULL) {
        printf("failed to register agent because following error\n");
        g_print("g_dbus_connection_call_sync error: '%s'\n", error->message);
        return -1;
    }

    printf("start main loop to waiting for incoming notification\n");
    g_main_loop_run(main_loop);
    g_bus_unown_name(owner_id);
    return 0;
}
